@file:Suppress("MagicNumber")

package com.google.android.catalog.app.compose.sample.polar

import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.unit.dp
import com.gitee.wsl.common.ui.draw.style.AreaStyle
import com.gitee.wsl.common.ui.draw.style.LineStyle
import com.gitee.wsl.compose.chart.Chart
import com.gitee.wsl.compose.chart.ChartLayout
import com.gitee.wsl.compose.chart.ExperimentalKoalaPlotApi
import com.gitee.wsl.compose.chart.KoalaPlotTheme.axisThemeStyle
import com.gitee.wsl.compose.chart.generateHueColorPalette
import com.gitee.wsl.compose.chart.legend.Flow
import com.gitee.wsl.compose.chart.legend.Legend
import com.gitee.wsl.compose.chart.legend.LegendLocation
import com.gitee.wsl.compose.chart.polar.model.DefaultPolarPoint
import com.gitee.wsl.compose.chart.polar.PolarGraph
import com.gitee.wsl.compose.chart.polar.PolarPlotSeries
import com.gitee.wsl.compose.chart.polar.model.PolarPoint
import com.gitee.wsl.compose.chart.polar.RadialGridType
import com.gitee.wsl.compose.chart.polar.axis.rememberCategoryAngularAxisModel
import com.gitee.wsl.compose.chart.polar.axis.rememberFloatRadialAxisModel
import com.gitee.wsl.compose.chart.polar.style.PolarGraphDefaults
import com.gitee.wsl.compose.ui.widget.Symbol
import com.google.android.catalog.app.compose.sample.ChartTitle
import com.google.android.catalog.app.compose.sample.SampleView
import com.google.android.catalog.app.compose.sample.ThumbnailTheme
import com.google.android.catalog.app.compose.sample.padding
import com.google.android.catalog.app.compose.sample.paddingMod
import kotlin.random.Random

val spiderPlotSample = object : SampleView {
    override val name: String = "Spider Plot"

    override val thumbnail = @Composable {
        ThumbnailTheme {
            SpiderPlotSample(true, name)
        }
    }

    override val content: @Composable () -> Unit = @Composable {
        SpiderPlotSample(false, "")
    }
}

// Generate random data
private val categories = listOf("Category 1", "Category 2", "Category 3", "Category 4", "Category 5")
private val seriesNames = listOf("Series 1", "Series 2", "Series 3")
private val data: List<List<PolarPoint<Float, String>>> = buildList {
    seriesNames.forEach { _ ->
        add(
            buildList {
                categories.forEach { category ->
                    add(DefaultPolarPoint(Random.nextDouble(1.0, 5.0).toFloat(), category))
                }
            }
        )
    }
}

@OptIn(ExperimentalKoalaPlotApi::class)
@Composable
@Suppress("MagicNumber")
private fun SpiderPlotSample(thumbnail: Boolean, title: String) {
    ChartLayout(
        modifier = paddingMod,
        title = { ChartTitle(title) },
        legend = { LegendView(thumbnail) },
        legendLocation = LegendLocation.BOTTOM
    ) {
        val angularAxisGridLineStyle = if (thumbnail) {
            LineStyle(SolidColor(Color.LightGray), strokeWidth = 1.dp)
        } else {
            axisThemeStyle.majorGridlineStyle
        }

        Chart.PolarGraph(
            rememberFloatRadialAxisModel((0..5).toList().map { it.toFloat() }),
            rememberCategoryAngularAxisModel(categories),
            radialAxisLabels = { if (!thumbnail) Text(it.toString()) },
            { if (!thumbnail) Text(it) },
            polarGraphStyle = PolarGraphDefaults.Default()
                .copy(
                    radialGridType = RadialGridType.LINES,
                    angularAxisGridLineStyle = angularAxisGridLineStyle,
                    radialAxisGridLineStyle = angularAxisGridLineStyle
                )
        ) {
            data.forEachIndexed { index, seriesData ->
                PolarPlotSeries(
                    seriesData,
                    lineStyle = LineStyle(SolidColor(palette[index]), strokeWidth = 1.5.dp),
                    areaStyle = AreaStyle(SolidColor(palette[index]), alpha = 0.3f),
                    symbols = {
                        Symbol(shape = CircleShape, fillBrush = SolidColor(palette[index]))
                    }
                )
            }
        }
    }
}

private val palette = generateHueColorPalette(seriesNames.size)

@Composable
private fun LegendView(thumbnail: Boolean = false) {
    if (!thumbnail) {
        Surface(shadowElevation = 2.dp) {
            Legend.Flow(
                itemCount = seriesNames.size,
                symbol = { i ->
                    Symbol(
                        shape = CircleShape,
                        modifier = Modifier.size(padding),
                        fillBrush = SolidColor(palette[i])
                    )
                },
                label = { i ->
                    Text(seriesNames[i])
                },
                modifier = paddingMod
            )
        }
    }
}
